﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.DataSourcesRaster;
using ESRI.ArcGIS.Display;

namespace PlanningGIS.ArcGIS
{
    /// <summary>
    /// 概述：ESRI.ArcGIS.Geodatabase 帮助类<br />
    /// </summary>
    [ComVisible(true)]
    public static class GeodatabaseHelper
    {
        #region 数据集
        /// <summary>
        /// 创建数据集，若数据集已存在，则打开已有的数据集，否则自动创建
        /// </summary>
        /// <param name="workspace">工作空间</param>
        /// <param name="name">名称</param>
        /// <param name="spatialReference">坐标系</param>
        /// <returns>要素集</returns>
        public static IFeatureDataset CreateFeatureDataset(IWorkspace workspace, string name, ISpatialReference spatialReference)
        {
            if (((IWorkspace2)workspace).get_NameExists(esriDatasetType.esriDTFeatureDataset, name.Trim()))
            {
                IFeatureWorkspace featureWorkspace = workspace as IFeatureWorkspace;
                return featureWorkspace.OpenFeatureDataset(name);
            }
            return (workspace as IFeatureWorkspace).CreateFeatureDataset(name, spatialReference);
        }

        /// <summary>
        /// 打开数据集，若数据集不存在，则返回null
        /// </summary>
        /// <param name="workspace">工作空间</param>
        /// <param name="name">要素集名称</param>
        /// <returns>要素集</returns>
        public static IFeatureDataset OpenFeatureDataset(IWorkspace workspace, string name)
        {
            if (((IWorkspace2)workspace).get_NameExists(esriDatasetType.esriDTFeatureDataset, name.Trim()))
            {
                IFeatureWorkspace featureWorkspace = workspace as IFeatureWorkspace;
                return featureWorkspace.OpenFeatureDataset(name);
            }
            return null;
        }

        /// <summary>
        /// 删除数据集IFeatureDataset
        /// </summary>
        /// <param name="workspace">工作空间</param>
        /// <param name="name">数据集名称</param>
        /// <returns></returns>
        public static bool DeleteFeatureDataset(IWorkspace workspace, string name)
        {
            IFeatureDataset featClass = OpenFeatureDataset(workspace, name);
            if (featClass == null) return true;
            return DeleteDataset(featClass as IDataset);
        }

        /// <summary>
        /// 删除数据对象IDataset，可以为要素类或数据集
        /// </summary>
        /// <param name="dataset">要删除的数据对象</param>
        /// <returns></returns>
        public static bool DeleteDataset(IDataset dataset)
        {
            if (dataset == null) return true;
            bool suc = false;
            if (dataset.CanDelete())
            {
                dataset.Delete();
                suc = true;
            }
            dataset = null;
            return suc;
        }
        #endregion

        #region 要素类

        /// <summary>
        /// 根据一个已有的要素类在数据库中创建一个新的要素类
        /// </summary>
        /// <param name="workspace">要创建要素类的工作空间</param>
        /// <param name="newClassName">要创建的要素类的名称</param>
        /// <param name="twofeatureClass">已有的要素类</param>
        /// <param name="fieldLength">创建临时图层时可能需要将所有字段都设为字符串</param>
        /// <returns></returns>
        public static IFeatureClass CreateFeatureClass(IFeatureWorkspace workspace, string newClassName, IFeatureClass twofeatureClass, int fieldLength = 0)
        {
            string shpFieldName = twofeatureClass.ShapeFieldName;
            IFields newFields = new Fields() as IFields;
            esriFeatureType FeatureType = twofeatureClass.FeatureType;
            IFeatureClassDescription fcDesc = new FeatureClassDescription() as IFeatureClassDescription;
            IObjectClassDescription ocDesc = (IObjectClassDescription)fcDesc;
            if (fieldLength == 0)
            {
                newFields = twofeatureClass.Fields;
            }
            else
            {
                IFieldsEdit fieldsEdit = newFields as IFieldsEdit;
                IFields pFields = twofeatureClass.Fields;
                for (int i = 0; i < pFields.FieldCount; i++)
                {
                    IField f = pFields.get_Field(i);
                    if (f.Type == esriFieldType.esriFieldTypeGeometry) continue;
                    if (f.Type == esriFieldType.esriFieldTypeOID) continue;
                    if (f.Type == esriFieldType.esriFieldTypeGUID) continue;
                    if (!f.Editable) continue;
                    IFieldEdit newItemFieldEdit = (IFieldEdit)f;
                    newItemFieldEdit.Type_2 = esriFieldType.esriFieldTypeString;
                    newItemFieldEdit.Length_2 = fieldLength;
                    fieldsEdit.AddField(f);
                }
            }
            newFields = GetValidFields((IWorkspace)workspace, newFields);
            IFeatureClass featcls = workspace.CreateFeatureClass(newClassName, newFields, ocDesc.InstanceCLSID, ocDesc.ClassExtensionCLSID, FeatureType, shpFieldName, "");
            newFields = null;
            return featcls;
        }

        /// <summary>
        /// 在工作空间中创建要素类
        /// </summary>
        /// <param name="workspace">工作空间</param>
        /// <param name="newClassName">要创建的要素类的名称</param>
        /// <param name="fields">字段</param>
        /// <returns>要素类</returns>
        public static IFeatureClass CreateFeatureClass(IWorkspace workspace, string newClassName, IFields fields)
        {
            fields = GetValidFields(workspace, fields);
            IObjectClassDescription objectClassDescription = new FeatureClassDescription() as IObjectClassDescription;
            return (workspace as IFeatureWorkspace).CreateFeatureClass(newClassName, fields, objectClassDescription.InstanceCLSID, objectClassDescription.ClassExtensionCLSID, esriFeatureType.esriFTSimple, "SHAPE", "");
        }

        /// <summary>
        /// 在工作空间中创建要素类
        /// </summary>
        /// <param name="workspace">工作空间</param>
        /// <param name="className">要创建的要素类的名称</param>
        /// <param name="fields">字段,不包含默认字段</param>
        /// <param name="geometryType">空间类型</param>
        /// <param name="spatialReference">空间参考</param>
        /// <returns></returns>
        public static IFeatureClass CreateFeatureClass(IWorkspace workspace, string className, IFields fields, esriGeometryType geometryType, ISpatialReference spatialReference = null)
        {
            if (fields == null) fields = new Fields();
            fields.AddDefaultFields(geometryType, spatialReference);
            fields = GetValidFields(workspace, fields);
            IObjectClassDescription objectClassDescription = new FeatureClassDescription() as IObjectClassDescription;
            return (workspace as IFeatureWorkspace).CreateFeatureClass(className, fields, objectClassDescription.InstanceCLSID, objectClassDescription.ClassExtensionCLSID, esriFeatureType.esriFTSimple, "SHAPE", "");
        }

        /// <summary>
        /// 在数据集中创建要素类
        /// </summary>
        /// <param name="featureDataset">数据集对象</param>
        /// <param name="newClassName">要创建的要素类的名称</param>
        /// <param name="fields">字段</param>
        /// <returns>要素类</returns>
        public static IFeatureClass CreateFeatureClass(IFeatureDataset featureDataset, string newClassName, IFields fields)
        {
            fields = GetValidFields(featureDataset.Workspace, fields);
            IObjectClassDescription objectClassDescription = new FeatureClassDescription() as IObjectClassDescription;
            return featureDataset.CreateFeatureClass(newClassName, fields, objectClassDescription.InstanceCLSID, objectClassDescription.ClassExtensionCLSID, esriFeatureType.esriFTSimple, "SHAPE", "");
        }

        /// <summary>
        /// 在数据集中创建要素类
        /// </summary>
        /// <param name="workspace">工作空间</param>
        /// <param name="newClassName">要素类名称</param>
        /// <param name="fields">字段</param>
        /// <param name="featureDatasetName">数据集名称，不能为空</param>
        /// <returns>要素类</returns>
        public static IFeatureClass CreateFeatureClass(IWorkspace workspace, string newClassName, IFields fields, string featureDatasetName)
        {
            if (string.IsNullOrWhiteSpace(featureDatasetName)) return null;
            IFeatureDataset featureDataset = OpenFeatureDataset(workspace, featureDatasetName);
            if (featureDataset == null) return null;
            return CreateFeatureClass(featureDataset, newClassName, fields);
        }

        /// <summary>
        /// 创建内存要素类
        /// </summary>
        /// <param name="name">要素类的名称</param>
        /// <param name="fields">要创建的字段，可以自动添加OBJECTID和SHAPE字段</param>
        /// <param name="geometryType">空间类型</param>
        /// <param name="spatialReference">空间参考</param>
        /// <returns></returns>
        public static IFeatureClass CreateMemoryFeatureClass(string name, IFields fields, esriGeometryType geometryType, ISpatialReference spatialReference = null)
        {
            IWorkspaceFactory wksfac = new InMemoryWorkspaceFactory();// 创建内存工作空间  
            IWorkspaceName wksname = wksfac.Create("", "Temp", null, 0);
            IName iname = (IName)wksname;
            IWorkspace memoryWS = (IWorkspace)iname.Open();
            if (fields == null) fields = new Fields();
            fields.AddDefaultFields(geometryType, spatialReference);
            IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)memoryWS;
            IFeatureClass featureClass = featureWorkspace.CreateFeatureClass(name, fields, null, null, esriFeatureType.esriFTSimple, "SHAPE", "");
            return featureClass;
        }

        /// <summary>
        /// 根据一个已有的注记层创建一个新的注记层，套用已有注记的显示比例和样式
        /// </summary>
        /// <param name="workspace">目标工作空间</param>
        /// <param name="datasetname">注记要素类名称</param>
        /// <param name="fields">除标准字段外的自定义的字段</param>
        /// <param name="twoAnnoCls">已有的注记层</param>
        /// <param name="featDataset">数据集对象</param>
        /// <param name="spatialRef">空间参考</param>
        /// <returns></returns>
        public static IFeatureClass CreateAnnotationFeatureClass(IWorkspace workspace, string datasetname, IFields fields,
            IFeatureClass twoAnnoCls, IFeatureDataset featDataset = null, ISpatialReference spatialRef = null)
        {
            IFeatureWorkspaceAnno annoWks = workspace as IFeatureWorkspaceAnno;
            if (annoWks == null) return null;
            if (twoAnnoCls == null)
            {
                return CreateAnnotationFeatureClass(workspace, datasetname, fields, 0, esriUnits.esriMeters, null, featDataset, spatialRef);
            }
            IFeatureClass annoCls = twoAnnoCls as IFeatureClass;
            IFeatureClassExtension clsExt = annoCls.Extension as IFeatureClassExtension;
            IAnnotationClassExtension annoExt = clsExt as IAnnotationClassExtension;
            ISymbolCollection symCol = annoExt.SymbolCollection;
            symCol.Reset();
            ISymbolIdentifier itmsuym = symCol.Next();
            ITextSymbol sym = itmsuym.Symbol as ITextSymbol;
            return CreateAnnotationFeatureClass(workspace, datasetname, fields, annoExt.ReferenceScale,
                annoExt.ReferenceScaleUnits, sym, featDataset, spatialRef);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="workspace"></param>
        /// <param name="datasetname"></param>
        /// <param name="fields"></param>
        /// <param name="scale"></param>
        /// <param name="units"></param>
        /// <param name="sym"></param>
        /// <param name="featureDataset"></param>
        /// <param name="spatialRef"></param>
        /// <returns></returns>
        public static IFeatureClass CreateAnnotationFeatureClass(IWorkspace workspace, string datasetname, IFields fields,
            double scale, esriUnits units = esriUnits.esriMeters, ITextSymbol sym = null, IFeatureDataset featureDataset = null, ISpatialReference spatialRef = null)
        {
            ILabelEngineLayerProperties lbllyrProperties = new LabelEngineLayerProperties() as ILabelEngineLayerProperties;
            IAnnotateLayerProperties annolyrProperties = (IAnnotateLayerProperties)lbllyrProperties;
            annolyrProperties.Class = "Annotation Class 1";
            if (sym != null) lbllyrProperties.Symbol = sym;
            ITextSymbol annotxtSymbol = lbllyrProperties.Symbol;
            ISymbol annoSymbol = (ISymbol)annotxtSymbol;

            ISymbolCollection symCol = new SymbolCollection();
            ISymbolCollection2 symCol2 = (ISymbolCollection2)symCol;
            ISymbolIdentifier2 symIdentifier2 = null;
            symCol2.AddSymbol(annoSymbol, "Annotation Class 1", out symIdentifier2);
            lbllyrProperties.SymbolID = symIdentifier2.ID;

            IAnnotateLayerPropertiesCollection annolyrPropsCollection = new AnnotateLayerPropertiesCollection();
            annolyrPropsCollection.Add(annolyrProperties);

            IGraphicsLayerScale graphicsLayerScale = new GraphicsLayerScale();
            if (scale != 0)
            { 
                graphicsLayerScale.ReferenceScale = scale; 
            }
            graphicsLayerScale.Units = units;
            IOverposterProperties overposterProperties = new BasicOverposterProperties();
            IObjectClassDescription des = new AnnotationFeatureClassDescription();
            IFeatureClassDescription fcDes = (IFeatureClassDescription)des;

            IFields rqFields = des.RequiredFields;
            int shapefdIdx = rqFields.FindField(fcDes.ShapeFieldName);
            IField shapeField = rqFields.get_Field(shapefdIdx);
            IGeometryDef geometryDef = shapeField.GeometryDef;
            IGeometryDefEdit geometryDefEdit = (IGeometryDefEdit)geometryDef;
            if (featureDataset != null) geometryDefEdit.SpatialReference_2 = (featureDataset as IGeoDataset).SpatialReference;
            else
            {
                if (spatialRef != null) geometryDefEdit.SpatialReference_2 = spatialRef;
            }
            IAnnotationLayerFactory annotationLayerFactory = new FDOGraphicsLayerFactory() as IAnnotationLayerFactory;
            IAnnotationLayer annotationLayer = annotationLayerFactory.CreateAnnotationLayer((IFeatureWorkspace)workspace, featureDataset, datasetname, geometryDef, null,
                annolyrPropsCollection, graphicsLayerScale, symCol, false, false, false, true, overposterProperties, "");
            IFeatureLayer featureLayer = (IFeatureLayer)annotationLayer;
            IFeatureClass featureClass = featureLayer.FeatureClass;
            if (fields != null && fields.FieldCount > 0)
            {
                for (int i = 0; i < fields.FieldCount; i++)
                {
                    if (featureClass.Fields.FindField(fields.get_Field(i).Name) == -1)
                        featureClass.AddField(fields.get_Field(i));
                }
            }
            return featureClass;
        }

        ///// <summary>
        ///// 创建注记要素类
        ///// </summary>
        ///// <param name="workspace">工作空间</param>
        ///// <param name="featDataset">数据集</param>
        ///// <param name="featureClassName">注记要素类名称</param>
        ///// <param name="fields">字段</param>
        ///// <param name="scale">显示比例尺</param>
        ///// <param name="unit">单位</param>
        ///// <returns></returns>
        //public static IFeatureClass CreateAnnotationFeatureClass(IFeatureWorkspace workspace, IFeatureDataset featDataset, string featureClassName,
        //    IFields fields, double scale, esriUnits unit = esriUnits.esriMeters)
        //{
        //    IFeatureWorkspaceAnno annoWks = workspace as IFeatureWorkspaceAnno;
        //    if (annoWks == null) return null;
        //    IGraphicsLayerScale graphicLayerScale = new GraphicsLayerScale();
        //    graphicLayerScale.Units = unit;
        //    graphicLayerScale.ReferenceScale = scale;

        //    stdole.IFontDisp myFont = new stdole.StdFont() as stdole.IFontDisp;
        //    myFont.Name = "宋体";
        //    myFont.Size = 8;

        //    IRgbColor myColor = new RgbColor();
        //    myColor.Red = 0;
        //    myColor.Green = 0;
        //    myColor.Blue = 0;

        //    IFormattedTextSymbol myTextSymbol = new TextSymbol();
        //    myTextSymbol.Font = myFont;
        //    myTextSymbol.Angle = 0;
        //    myTextSymbol.RightToLeft = true;
        //    myTextSymbol.VerticalAlignment = esriTextVerticalAlignment.esriTVABaseline;
        //    myTextSymbol.HorizontalAlignment = esriTextHorizontalAlignment.esriTHAFull;
        //    myTextSymbol.CharacterSpacing = 10;
        //    myTextSymbol.Case = esriTextCase.esriTCNormal;
        //    myTextSymbol.Color = myColor;

        //    ISymbolCollection symbolCollection = new SymbolCollection();
        //    symbolCollection.set_Symbol(0, (ISymbol)myTextSymbol);

        //    IAnnotateLayerProperties annoProps = new LabelEngineLayerProperties() as IAnnotateLayerProperties;
        //    annoProps.FeatureLinked = false;
        //    annoProps.AddUnplacedToGraphicsContainer = false;
        //    annoProps.CreateUnplacedElements = true;
        //    annoProps.DisplayAnnotation = true;
        //    annoProps.UseOutput = true;

        //    ILabelEngineLayerProperties layerEngineLayerProps = (ILabelEngineLayerProperties)annoProps;
        //    IAnnotationExpressionEngine annoExpressionEngine = new AnnotationVBScriptEngine();
        //    layerEngineLayerProps.ExpressionParser = annoExpressionEngine;
        //    layerEngineLayerProps.Expression = "[DESCRIPTION]";
        //    layerEngineLayerProps.IsExpressionSimple = true;
        //    layerEngineLayerProps.Offset = 0;
        //    layerEngineLayerProps.SymbolID = 0;
        //    layerEngineLayerProps.Symbol = myTextSymbol;
        //    IAnnotateLayerTransformationProperties annoLayerTransProp = (IAnnotateLayerTransformationProperties)annoProps;
        //    annoLayerTransProp.ReferenceScale = graphicLayerScale.ReferenceScale;
        //    annoLayerTransProp.Units = graphicLayerScale.Units;
        //    annoLayerTransProp.ScaleRatio = 1;
        //    IAnnotateLayerPropertiesCollection annoPropsColl = new AnnotateLayerPropertiesCollection();
        //    annoPropsColl.Add(annoProps);

        //    IObjectClassDescription objclsdes = new AnnotationFeatureClassDescription();
        //    IFeatureClassDescription fclsdes = (IFeatureClassDescription)objclsdes;
        //    IFields fds = objclsdes.RequiredFields;
        //    if (fields != null && fields.FieldCount > 0)
        //    {
        //        IFieldsEdit fdsEdt = fds as IFieldsEdit;
        //        for (int i = 0; i < fields.FieldCount; i++)
        //        {
        //            fdsEdt.AddField(fields.get_Field(i));
        //        }
        //    }

        //    IFeatureClass clsText = annoWks.CreateAnnotationClass(featureClassName, fds, objclsdes.InstanceCLSID, objclsdes.ClassExtensionCLSID,
        //        fclsdes.ShapeFieldName, "", featDataset, null, annoProps, graphicLayerScale, symbolCollection, false);

        //    Marshal.ReleaseComObject(objclsdes);
        //    objclsdes = null;
        //    Marshal.ReleaseComObject(fclsdes);
        //    fclsdes = null;
        //    Marshal.ReleaseComObject(graphicLayerScale);
        //    graphicLayerScale = null;
        //    Marshal.ReleaseComObject(myTextSymbol);
        //    myTextSymbol = null;
        //    Marshal.ReleaseComObject(symbolCollection);
        //    symbolCollection = null;
        //    Marshal.ReleaseComObject(annoProps);
        //    annoProps = null;
        //    Marshal.ReleaseComObject(layerEngineLayerProps);
        //    layerEngineLayerProps = null;
        //    Marshal.ReleaseComObject(annoLayerTransProp);
        //    annoLayerTransProp = null;
        //    Marshal.ReleaseComObject(annoPropsColl);
        //    annoPropsColl = null;
        //    return clsText;
        //}

        ///// <summary>
        ///// 创建标准的注记类
        ///// </summary>
        ///// <param name="featureWorkspace"></param>
        ///// <param name="featureDataset"></param>
        ///// <param name="className"></param>
        ///// <param name="spatialReference"></param>
        ///// <param name="scale"></param>
        ///// <param name="units"></param>
        ///// <param name="keyword"></param>
        ///// <returns></returns>
        //public static IFeatureClass CreateStandardAnnotationClass(IFeatureWorkspace featureWorkspace, IFeatureDataset featureDataset, string className,
        //        ISpatialReference spatialReference, int scale, esriUnits units, string keyword = "")
        //{
        //    ILabelEngineLayerProperties lbllyrProperties = new LabelEngineLayerProperties() as ILabelEngineLayerProperties;
        //    IAnnotateLayerProperties annolyrProperties = (IAnnotateLayerProperties)lbllyrProperties;
        //    annolyrProperties.Class = "Annotation Class 1";
        //    ITextSymbol annotxtSymbol = lbllyrProperties.Symbol;
        //    ISymbol annoSymbol = (ISymbol)annotxtSymbol;

        //    ISymbolCollection symCol = new SymbolCollection();
        //    ISymbolCollection2 symCol2 = (ISymbolCollection2)symCol;
        //    ISymbolIdentifier2 symIdentifier2 = null;
        //    symCol2.AddSymbol(annoSymbol, "Annotation Class 1", out symIdentifier2);
        //    lbllyrProperties.SymbolID = symIdentifier2.ID;

        //    IAnnotateLayerPropertiesCollection annolyrPropsCollection = new AnnotateLayerPropertiesCollection();
        //    annolyrPropsCollection.Add(annolyrProperties);

        //    IGraphicsLayerScale graphicsLayerScale = new GraphicsLayerScale();
        //    graphicsLayerScale.ReferenceScale = scale;
        //    graphicsLayerScale.Units = units;
        //    IOverposterProperties overposterProperties = new BasicOverposterProperties();
        //    IObjectClassDescription des = new AnnotationFeatureClassDescription();
        //    IFeatureClassDescription fcDes = (IFeatureClassDescription)des;
            
        //    IFields rqFields = des.RequiredFields;
        //    int shapefdIdx = rqFields.FindField(fcDes.ShapeFieldName);
        //    IField shapeField = rqFields.get_Field(shapefdIdx);
        //    IGeometryDef geometryDef = shapeField.GeometryDef;
        //    IGeometryDefEdit geometryDefEdit = (IGeometryDefEdit)geometryDef;
        //    geometryDefEdit.SpatialReference_2 = spatialReference;

        //    IAnnotationLayerFactory annotationLayerFactory = new FDOGraphicsLayerFactory() as IAnnotationLayerFactory;
        //    IAnnotationLayer annotationLayer = annotationLayerFactory.CreateAnnotationLayer(featureWorkspace, featureDataset, className, geometryDef, null,
        //        annolyrPropsCollection, graphicsLayerScale, symCol, false, false, false, true, overposterProperties, keyword);
        //    IFeatureLayer featureLayer = (IFeatureLayer)annotationLayer;
        //    IFeatureClass featureClass = featureLayer.FeatureClass;
        //    return featureClass;
        //}

        /// <summary>
        /// 根据shp图层名称获取shp图层
        /// </summary>
        /// <param name="fullname">shp图层全路径名称</param>
        /// <returns></returns>
        public static IFeatureClass OpenShpFeatureClass(string fullname)
        {
            FileInfo fi = new FileInfo(fullname);
            string dirname = fi.DirectoryName;
            string filename = fi.Name;
            IWorkspaceFactory workspaceFactory = new ShapefileWorkspaceFactory() as IWorkspaceFactory;
            IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspaceFactory.OpenFromFile(dirname, 0);
            IFeatureClass featureClass = featureWorkspace.OpenFeatureClass(filename);
            Marshal.FinalReleaseComObject(workspaceFactory);
            return featureClass;
        }

        /// <summary>
        /// 打开要素类
        /// </summary>
        /// <param name="fullname">要素类全路径</param>
        /// <returns></returns>
        public static IFeatureClass OpenFeatureClass(string fullname)
        {
            if (fullname.ToLower().Trim().EndsWith(".shp")) return OpenShpFeatureClass(fullname);
            IWorkspace wks = WorkspaceHelper.OpenWorkspace2(fullname);
            if (wks == null) return null;
            int idx = fullname.LastIndexOf("\\");
            if (idx < 0) return null;
            string clsname = fullname.Substring(idx + 1);
            return OpenFeatureClass(wks, clsname);
        }

        /// <summary>
        /// 打开要素类。
        /// </summary>
        /// <param name="workspace">要素类所在的工作空间。</param>
        /// <param name="featureClassName">要素类的名称。</param>
        /// <returns>要素类。</returns>
        public static IFeatureClass OpenFeatureClass(IWorkspace workspace, string featureClassName)
        {
            if (((IWorkspace2)workspace).get_NameExists(esriDatasetType.esriDTFeatureClass, featureClassName.Trim()))
            {
                IFeatureWorkspace featureWorkspace = workspace as IFeatureWorkspace;
                return featureWorkspace.OpenFeatureClass(featureClassName.Trim());
            }
            return null;
        }

        /// <summary>
        ///  根据图层数据集的名称（IFeatureClass名称）删除工作空间中存在的数据集IFeatureClass
        /// </summary>
        /// <param name="workspace">数据集所在的工作空间</param>
        /// <param name="name">数据集的名称</param>
        /// <returns></returns>
        public static bool DeleteFeatureClass(IWorkspace workspace, string name)
        {
            IFeatureClass featClass = OpenFeatureClass(workspace, name.Trim());
            if (featClass == null) return true;
            return DeleteDataset(featClass as IDataset);
        }

        /// <summary>
        /// 删除栅格数据集
        /// </summary>
        /// <param name="fullpath"></param>
        public static bool DeleteRaster(string fullpath)
        {
            string fpath = System.IO.Path.GetDirectoryName(fullpath);
            string fname = System.IO.Path.GetFileName(fullpath);
            IRasterWorkspace2 rwk = new RasterWorkspaceFactory().OpenFromFile(fpath, 0) as IRasterWorkspace2;
            IRasterDataset pGeodata = rwk.OpenRasterDataset(fname);
            if (pGeodata == null) return true;
            IDataset dataset = pGeodata as IDataset;
            return DeleteDataset(dataset);
        }
        /// <summary>
        /// 查询工作空间中是否存在指定名称的数据集
        /// </summary>
        /// <param name="workspace">工作空间</param>
        /// <param name="name">数据集名称</param>
        /// <returns></returns>
        public static bool ExistsFeatureClass(IWorkspace workspace, string name)
        {
            if (((IWorkspace2)workspace).get_NameExists(esriDatasetType.esriDTFeatureClass, name.Trim()))
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// 获取工作空间中的所有IFeatureClass
        /// </summary>
        /// <param name="workspace">工作空间</param>
        /// <param name="filter">要筛选的条件，及名称包含的内容</param>
        /// <returns></returns>
        [Obsolete("已废弃")]
        public static List<IFeatureClass> GetAllFeatureClass(IWorkspace workspace, string filter = "")
        {
            List<IFeatureClass> fs = new List<IFeatureClass>();
            List<string> names = GetAllFeatureClassName(workspace, filter);
            foreach (string name in names)
            {
                if (!string.IsNullOrWhiteSpace(filter))
                    if (!name.Contains(filter)) continue;
                fs.Add(OpenFeatureClass(workspace, name));
            }
            return fs;
        }

        /// <summary>
        /// 获取工作空间中所有FeatureClass的名称
        /// </summary>
        /// <param name="workspace">工作空间</param>
        /// <param name="filter">要筛选的条件，及名称包含的内容</param>
        /// <param name="containds">是否包含数据集中的要素类</param>
        /// <returns></returns>
        public static List<string> GetAllFeatureClassName(IWorkspace workspace, string filter = "", bool containds = true)
        {
            List<string> names = new List<string>();
            IEnumDatasetName ipDatasetEnumName = workspace.get_DatasetNames(esriDatasetType.esriDTAny);
            ipDatasetEnumName.Reset();
            IDatasetName datasetName = null;
            while ((datasetName = ipDatasetEnumName.Next()) != null)
            {
                if (datasetName is IFeatureClassName)
                {
                    if (!string.IsNullOrWhiteSpace(filter))
                        if (!datasetName.Name.Contains(filter)) continue;
                    names.Add(datasetName.Name);
                }
                else if (datasetName is IFeatureDatasetName)
                {
                    if (containds)
                    {
                        IEnumDatasetName fdsnames = (datasetName as IFeatureDatasetName).FeatureClassNames;
                        IDatasetName dsname2 = null;
                        while ((dsname2 = fdsnames.Next()) != null)
                        {
                            if (dsname2 is IFeatureClassName)
                            {
                                if (!string.IsNullOrWhiteSpace(filter))
                                    if (!dsname2.Name.Contains(filter)) continue;
                                names.Add(dsname2.Name);
                            }
                        }
                    }                    
                }
            }
            return names;
        }
        
        /// <summary>
        /// 获取指定数据对象（工作空间、数据集）中的所有要素类
        /// </summary>
        /// <param name="dataset">工作空间（IWorkspace as IDataset）、数据集</param>
        /// <param name="filter">要筛选的条件，及名称包含的内容</param>
        /// <returns></returns>
        public static List<IFeatureClass> GetAllFeatureClass(IDataset dataset, string filter = "")
        {
            if (dataset == null) return null;
            List<IFeatureClass> fs = new List<IFeatureClass>();
            if (dataset is IFeatureClass)
            {
                fs.Add(dataset as IFeatureClass);
                return fs;
            }
            IEnumDataset emDs = dataset.Subsets;
            emDs.Reset();
            IDataset ds = null;
            while ((ds = emDs.Next()) != null)
            {
                if (ds is IFeatureClass)
                {
                    if (!string.IsNullOrWhiteSpace(filter)) if (!ds.Name.Contains(filter)) continue;
                    fs.Add(ds as IFeatureClass);
                }
                else if (ds is IFeatureDataset)
                {
                    IEnumDataset emDs2 = (ds as IFeatureDataset).Subsets;
                    IDataset ds2 = null;
                    while ((ds2 = emDs2.Next()) != null)
                    {
                        if (ds2 is IFeatureClass)
                        {
                            if (!string.IsNullOrWhiteSpace(filter))
                                if (!ds2.Name.Contains(filter)) continue;
                            fs.Add(ds2 as IFeatureClass);
                        }
                    }
                }
            }
            return fs;
        }
        
        
        #endregion

        #region 数据表
        /// <summary>
        /// 打开数据表
        /// </summary>
        /// <param name="workspace">工作空间</param>
        /// <param name="name">数据表名称</param>
        /// <returns></returns>
        public static ITable OpenTable(IWorkspace workspace, string name)
        {
            if (((IWorkspace2)workspace).get_NameExists(esriDatasetType.esriDTTable, name.Trim()))
            {
                IFeatureWorkspace featureWorkspace = workspace as IFeatureWorkspace;
                return featureWorkspace.OpenTable(name);
            }
            return null;
        }

        /// <summary>
        /// 打开表文件 
        /// </summary>
        /// <param name="pathName">表文件存放的路径</param>
        /// <param name="tableName">表文件名</param>
        /// <returns>表</returns>
        public static ITable OpenTable(string pathName, string tableName)
        {
            IWorkspaceName workspaceName = new WorkspaceName() as IWorkspaceName;
            workspaceName.PathName = pathName;
            workspaceName.WorkspaceFactoryProgID = "esriDataSourcesFile.shapefileworkspacefactory";
            IDatasetName dataSetName = new TableName() as IDatasetName;
            dataSetName.Name = tableName;
            dataSetName.WorkspaceName = workspaceName;
            IName name = (IName)dataSetName;
            return (ITable)name.Open();
        }

        /// <summary>
        /// 删除数据表
        /// </summary>
        /// <param name="workspace">工作空间</param>
        /// <param name="name">数据表名称</param>
        /// <returns></returns>
        public static bool DeleteTable(IWorkspace workspace, string name)
        {
            ITable table = OpenTable(workspace, name);
            if (table == null)
                return true;
            return DeleteDataset(table as IDataset);
        }

        #endregion

        #region 数据库文件

        /// <summary>
        /// 打开dbf中的数据表
        /// </summary>
        /// <param name="fullname">dbf文件全路径</param>
        /// <returns></returns>
        public static ITable OpenDBF(string fullname)
        {
            FileInfo fi = new FileInfo(fullname);
            string dirname = fi.DirectoryName;
            string filename = fi.Name;
            filename = filename.Trim().Replace(fi.Extension, "");
            fi = null;
            IWorkspaceFactory workspaceFactory = new ShapefileWorkspaceFactory() as IWorkspaceFactory;
            IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspaceFactory.OpenFromFile(dirname, 0);
            ITable featureClass = featureWorkspace.OpenTable(filename);
            Marshal.FinalReleaseComObject(featureWorkspace);
            Marshal.FinalReleaseComObject(workspaceFactory);
            featureWorkspace = null;
            workspaceFactory = null;
            return featureClass;
        }

        #endregion

        #region 其他

        /// <summary>
        /// 获取验证后的字段信息
        /// </summary>
        /// <param name="workspace"></param>
        /// <param name="fields"></param>
        /// <returns></returns>
        public static IFields GetValidFields(IWorkspace workspace, IFields fields)
        {
            IFieldChecker fieldChecker = new ESRI.ArcGIS.Geodatabase.FieldChecker();
            IEnumFieldError enumFieldError = null;
            IFields validatedFields = null;
            fieldChecker.ValidateWorkspace = workspace;
            fieldChecker.Validate(fields, out enumFieldError, out validatedFields);
            return validatedFields;
        }

        /// <summary>
        /// 判断一个文件夹是否为ESRI的GRID数据
        /// </summary>
        /// <param name="fullPath"></param>
        /// <returns></returns>
        public static bool IsGRID(string fullPath)
        {
            fullPath = fullPath.TrimEnd('\\');
            if (Directory.Exists(fullPath) == false) return false;
            try
            {
                if (fullPath.Contains("System Volume Information")) return false;
                if (fullPath.Equals("C:\\Documents and Settings", StringComparison.CurrentCultureIgnoreCase)) return false;
                DirectoryInfo dInfo = new DirectoryInfo(fullPath);
                FileInfo[] fileInfos = dInfo.GetFiles("*.adf");
                if (fileInfos == null || fileInfos.Length == 0) return false;
                string path = fullPath.Substring(0, fullPath.LastIndexOf('\\'));
                string filename = fullPath.Substring(fullPath.LastIndexOf('\\') + 1);
                IPropertySet propertyset = new PropertySet() as IPropertySet;
                propertyset.SetProperty("DATABASE", path);
                IWorkspaceFactory2 workspaceFac = new RasterWorkspaceFactory() as IWorkspaceFactory2;
                IWorkspace workspace = workspaceFac.Open(propertyset, 0);
                IRasterWorkspace2 workspaceEx = workspace as IRasterWorkspace2;
                IRasterDataset dataset = workspaceEx.OpenRasterDataset(filename);
                return true;
            }
            catch //没有访问权限时会报异常
            {
                return false;
            }
        }
        #endregion


    }
}